package com.yc.clouduser.web;


import com.yc.clouduser.entity.User;
import com.yc.clouduser.util.JwtUtil;
import com.yc.clouduser.util.QRCodeUtil;
import com.yc.vcode.bean.Result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;

import javax.servlet.http.HttpSession;
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("qrcode")
@ServerEndpoint("/autoLogin/{token}")
public class QrCodeDo {

    public static final String MY_HEAD = "C:\\Users\\林志凯\\Desktop\\head.jpg";

    //获取二维码图片
    @RequestMapping(value = "image", produces = MediaType.IMAGE_JPEG_VALUE)
    public void image(String content, OutputStream out) throws Exception {
        QRCodeUtil.encode(content, MY_HEAD, out, true);
    }

    //访问手机的页面
    @RequestMapping(value = "mobile", produces = MediaType.IMAGE_JPEG_VALUE)
    public void toMobile(OutputStream out) throws Exception {
        image("http://192.168.149.84/mobile/index.html", out);
    }

    @Autowired
    RedisTemplate redisTemplate;

    //生成二维码
    @RequestMapping(value = "createLoginQrcode", produces = MediaType.IMAGE_JPEG_VALUE)
    public void createLoginQrcode(OutputStream out, HttpSession session) throws Exception {
        //生成令牌UUID
        String uuid = UUID.randomUUID().toString();
        ScanLoginInfo sli =new ScanLoginInfo(uuid, "未扫码", null);
        //存入redis
        ValueOperations opsForValue = redisTemplate.opsForValue();
        opsForValue.set("scanLogin:" + uuid, sli, 60, TimeUnit.SECONDS);
        //扫码内容
        String content = "http://192.168.149.84/cloud-user/qrcode/scanLoginQrcode?token=" + uuid;
        image(content, out);
        session.setAttribute("loginToken", uuid);
    }

    @Value("${vcode.session-key}")
    String sessionKey;

    @RequestMapping("scanLoginQrcode")
    public Result a(String token, HttpSession session) throws IOException {
        User user = (User) session.getAttribute(sessionKey);
        if(user == null){
            return new Result(0, "请先登录系统", null);
        }
        ValueOperations opsForValue = redisTemplate.opsForValue();
        ScanLoginInfo info = (ScanLoginInfo) opsForValue.get("scanLogin:" + token);
        if(info == null){
            return new Result(-1, "二维码失效", null);
        }
        info.setStatus("扫码成功");
        info.setMyInfo(user);
        opsForValue.set("scanLogin:" + token, info, 60, TimeUnit.SECONDS);

        //TODO  通知pc前端，扫码成功，pc要获取用户信息
        sessions.get(token).getBasicRemote().sendText("OK");

        return new Result(1, "扫码成功", null);
    }

    //存储websocket会话
    static HashMap<String, Session> sessions = new HashMap<>();

    //一建立连接，将会话存入info
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token){
        sessions.put(token, session);
        session.getUserProperties().put("token", token);
    }

    @OnClose
    public void onClose(Session session){
        String token = (String) session.getUserProperties().get("token");
        sessions.remove(token);
    }

    //自动登录
    @RequestMapping("autoLogin")
    public Result autoLogin(String token, HttpSession session) throws IOException {
        ValueOperations opsForValue = redisTemplate.opsForValue();
        ScanLoginInfo info = (ScanLoginInfo) opsForValue.get("scanLogin:" + token);
        User myinfo = info.getMyInfo();
        session.setAttribute("myinfo", myinfo);
        //转换
        Map<String, Object> map = new HashMap<>();
        map.put("id", myinfo.getId());
        map.put("name", myinfo.getName());
        map.put("email", myinfo.getEmail());
        map.put("pic", myinfo.getPic());
        map.put("status", myinfo.getStatus());
        String jwt = JwtUtil.createJWT(30, map);
        return new Result(1, "登录成功！", jwt);
    }

    @RequestMapping("getLoginToken")
    Result loginToken(@SessionAttribute(required = false) String loginToken){
        if(loginToken == null){
            return new Result(0, "令牌未生成", null);
        }else {
            return new Result(1, "令牌生成", loginToken);
        }
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class ScanLoginInfo implements java.io.Serializable{
    String uuid;
    String status = "未扫码";
    User myInfo;
}
